home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / Tumbler and Podium / Tumbler_menus.c < prev    next >
Encoding:
Text File  |  1995-11-13  |  25.5 KB  |  1,021 lines  |  [TEXT/MPS ]

  1. //        Tumbler_menus.c
  2. //
  3. //        Menu handling routines and utilities.
  4. //        
  5. //
  6. //        Author:        Nick Thompson & Pablo Fernicola, with thanks to the QuickDraw 3D team
  7. //
  8. //    Modification History:
  9. //
  10. //    11/25/94    Nick    Started Factoring for AppleEvent senders, cleanup
  11. //
  12. //        Copyright © 1992-95 Apple Computer, Inc., All Rights Reserved
  13.  
  14. #define FINAL
  15.  
  16. #include <Drag.h>
  17. #include <Desk.h>
  18. #include <Picker.h>
  19.  
  20. #include "Tumbler_globals.h"
  21. #include "Tumbler_prototypes.h"
  22. #include "Tumbler_resources.h"
  23. #include "Tumbler_AEVT.h"
  24.  
  25. #include "QD3DStorage.h"
  26. #include "QD3DIO.h"
  27. #include "QD3DView.h"
  28. #include "QD3DTransform.h"
  29. #include "QD3DDrawContext.h"
  30. #include "QD3DGeometry.h"
  31. #include "QD3DGroup.h"
  32. #include "QD3DShader.h"
  33. #include "QD3DLight.h"
  34. #include "QD3DRenderer.h"
  35. #include "QD3DAcceleration.h"
  36.  
  37. #include "Tumbler_menus.h"
  38. #include "Tumbler_document.h"
  39. #include "Tumbler_file.h"
  40. #include "Tumbler_windows.h"
  41. #include "Tumbler_PICTImport.h"
  42. #include "Tumbler_drag.h"
  43. #include "Tumbler_offscreen.h"
  44. #include "Tumbler_menus.h"
  45. #include "Tumbler_utility.h"
  46. #include "Tumbler_camera.h"
  47.  
  48. #define BETA_OR_LATER 1
  49.  
  50. #if !defined(BETA_OR_LATER) || (BETA_OR_LATER == 0)
  51. #include "Catwoman.h"
  52. #endif
  53.  
  54. static void DoCopy(DocumentPtr theDocument, Boolean cut);
  55. static short FindCheckItem(MenuHandle theMenu, short rangeStart, short rangeEnd);
  56. static short Check1Item(MenuHandle theMenu, short theItem, short rangeStart, short rangeEnd);
  57. static short ItemCheck(MenuHandle theMenu, short theItem);
  58. static short ToggleCheck(MenuHandle theMenu, short theItem);
  59. static void SetItemEnable(MenuHandle theMenu, short theItem, short enable);
  60. static short ItemStringToItem(Str255 theItemString, MenuHandle theMenu);
  61. static short FontToItem(short fontFamilyNumber);
  62. static short DoSpecialPaste(DocumentPtr theDocument);
  63. static void DoPaste(DocumentPtr theDocument);
  64.  
  65.  
  66. static void UpdateWindow( WindowPtr theWindow)
  67. {
  68.     GrafPtr    savedPort ;
  69.     
  70.     // just tell the toolbox that the window is bogus
  71.     GetPort(&savedPort) ;
  72.     SetPort(theWindow) ;
  73.     InvalRect( &theWindow->portRect ) ;
  74.     SetPort(savedPort) ;
  75. }
  76.  
  77.  
  78.  
  79.  
  80. static void DoCopy(DocumentPtr theDocument, Boolean cut)
  81. {
  82.     TQ3FileObject         fd;
  83.     TQ3StorageObject     st;
  84.     Handle                theData;
  85.     long                 anErr;
  86.     unsigned long        size;
  87.     PicHandle            thePicture;
  88.     GrafPtr                restorePort;
  89.     RGBColor            qdBgColor;
  90.     Boolean                didAllocate = false ;
  91.     
  92.     // Write the data to a strage object 
  93.  
  94.     // as of 1.0a3 handle storage objects break when increasing the size
  95.     // of the handle in increments with complex models.  To try to get
  96.     // around this we'll temporarily allocate a 1 meg handle. FIX THIS
  97.     if((theData = NewHandle( 1024 * 1024 )) != nil) {
  98.         MoveHHi( theData ) ;
  99.         HLock( theData ) ;
  100.         didAllocate = true ;
  101.         st = Q3HandleStorage_New( theData, GetHandleSize( theData ) );
  102.     }
  103.     else    
  104.         st = Q3HandleStorage_New(nil, 0);
  105.  
  106.     if (st == nil)
  107.     {
  108.         if( didAllocate )
  109.             DisposeHandle( theData ) ;
  110.         return;
  111.     }
  112.     
  113.     fd = Q3File_New();
  114.     
  115.     if (fd == nil) {
  116.         Q3Object_Dispose(st);
  117.         if( didAllocate )
  118.             DisposeHandle( theData ) ;
  119.         return;
  120.     }
  121.     
  122.     Q3File_SetStorage(fd, st);
  123.     
  124.         
  125.     Tumbler_WriteScene(fd, 
  126.                         false,
  127.                         theDocument) ;
  128.     
  129.     theData = nil; size = 0;
  130.     
  131.     if( Q3HandleStorage_Get(st, &theData, &size) == kQ3Failure ) {
  132.         Q3Object_Dispose(st);
  133.         if( didAllocate )
  134.             DisposeHandle( theData ) ;
  135.         return;
  136.     }
  137.     
  138.     /* Transfer the data to the scrap */
  139.     HLock(theData);
  140.     
  141.     GetPort( &restorePort);
  142.     SetPort( (GrafPtr) theDocument->theWindow);
  143.     
  144.     qdBgColor.red     = (unsigned short)65535;
  145.     qdBgColor.green = (unsigned short)65535;
  146.     qdBgColor.blue     = (unsigned short)65535;
  147.     RGBBackColor(&qdBgColor);
  148.     qdBgColor.red     = 0;
  149.     qdBgColor.green = 0;
  150.     qdBgColor.blue     = 0;
  151.     RGBForeColor(&qdBgColor);
  152.     thePicture = OpenPicture(&theDocument->theWindow->portRect);
  153.     EraseRect( &theDocument->theWindow->portRect ) ;
  154.     
  155.     if( DrawOffscreen(theDocument) == kQ3Failure ) {
  156.         goto memExit;
  157.     }
  158.     
  159.     ClosePicture();
  160.     
  161.     HLock( (Handle) thePicture);
  162.     
  163.     /* Initialize the scrap */
  164.     anErr = LoadScrap();
  165.     if (anErr != noErr) {
  166.         goto errorExit;
  167.     } else {
  168.         anErr = ZeroScrap();
  169.         if (anErr == noErr) {
  170.             anErr = PutScrap(size, '3DMF', (Ptr) *theData);
  171.             if (anErr == noErr) {
  172.                 anErr = PutScrap(GetHandleSize((Handle)thePicture), 'PICT', (Ptr) *thePicture);
  173.                 if (anErr == noErr) {
  174.                     anErr = UnloadScrap();
  175.                 }
  176.             }
  177.         }
  178.     }
  179.     
  180.     HUnlock(theData);
  181.  
  182.     if( cut == true ) {
  183.         Q3Object_Dispose(theDocument->documentGroup);
  184.         theDocument->documentGroup = nil;
  185.         SetPort(theDocument->theWindow) ;
  186.         InvalRect( &theDocument->theWindow->portRect) ;
  187.     }
  188.     
  189. errorExit:    
  190.     SetPort(restorePort);
  191.  
  192.     HUnlock((Handle)thePicture);
  193.     KillPicture(thePicture);
  194.     
  195. memExit:    
  196.     Q3Object_Dispose(st);
  197.     
  198.     if( didAllocate )
  199.         DisposeHandle( theData ) ;
  200.         
  201.     Q3Object_Dispose(fd);
  202.     return;
  203. }
  204.  
  205. //
  206. //    Given a range of menu items and a menu, FindCheckItem returns the
  207. //    item number of the first checked item. If no items in the range
  208. //    are checked, FindCheckItem returns 0 (zero).
  209. //
  210.  
  211.  
  212. static short FindCheckItem(MenuHandle theMenu, short rangeStart, short rangeEnd)
  213.  
  214. {    short        theMark;
  215.  
  216.     while (rangeStart <= rangeEnd) {
  217.         GetItemMark(theMenu, rangeStart, &theMark);
  218.         if (theMark == checkMark)
  219.             return(rangeStart);
  220.         rangeStart++;
  221.     }
  222.  
  223.     return(0);
  224. }
  225.  
  226.  
  227. //
  228. //    Check1Item checks a single menu item in a range of menu items. theItem is
  229. //    the item number to check. rangeStart and rangeEnd denote a range of menu
  230. //    items that theItem belongs to. Check1Item checks theItem and removes
  231. //    any checks from the other items in the given range. Check1Item returns
  232. //    the item number of the checked item if a newly checked item is selected.
  233. //    If theItem was already checked or theItem was outside of the given range,
  234. //    Check1Item returns 0 (zero).
  235. //
  236.  
  237. static short Check1Item(MenuHandle theMenu, short theItem, short rangeStart, short rangeEnd)
  238.  
  239. {    short        theMark;
  240.  
  241.     if ((theItem < rangeStart) || (theItem > rangeEnd))
  242.         return(0);
  243.  
  244.     while (rangeStart <= rangeEnd) {
  245.         if (rangeStart != theItem)
  246.             CheckItem(theMenu, rangeStart, false);
  247.         rangeStart++;
  248.     }
  249.  
  250.     GetItemMark(theMenu, theItem, &theMark);
  251.  
  252.     if (theMark != checkMark) {
  253.         CheckItem(theMenu, theItem, true);
  254.         return(theItem);
  255.     } else {
  256.         return(0);
  257.     }
  258. }
  259.  
  260.  
  261. //
  262. //    ItemCheck returns true if the given menu item is checked, false otherwise.
  263. //
  264.  
  265. static short ItemCheck(MenuHandle theMenu, short theItem)
  266.  
  267. {    short        theMark;
  268.  
  269.     GetItemMark(theMenu, theItem, &theMark);
  270.     return(theMark == checkMark);
  271.  
  272. }
  273.  
  274.  
  275. //
  276. //    ToggleCheck toggles the check mark on the given menu item. ToggleCheck
  277. //    returns true if the item becomes checked and false if the item becomes
  278. //    unchecked.
  279. //
  280.  
  281. static short ToggleCheck(MenuHandle theMenu, short theItem)
  282.  
  283. {    short        theMark;
  284.  
  285.     GetItemMark(theMenu, theItem, &theMark);
  286.     CheckItem(theMenu, theItem, theMark = (theMark != checkMark));
  287.     return(theMark);
  288. }
  289.  
  290.  
  291. //
  292. //    SetItemEnable enables or disables a menu item depending on the value
  293. //    of the enable parameter.
  294. //
  295.  
  296. static void SetItemEnable(MenuHandle theMenu, short theItem, short enable)
  297.  
  298. {
  299.     if (enable) {
  300.         EnableItem(theMenu, theItem);
  301.     } else {
  302.         DisableItem(theMenu, theItem);
  303.     }
  304. }
  305.  
  306.  
  307. //
  308. //    Given a string and a menu, ItemStringToItem will return the item number
  309. //    of the last item that matches the string.
  310. //
  311.  
  312. static short ItemStringToItem(Str255 theItemString, MenuHandle theMenu)
  313.  
  314. {    short        index;
  315.     Str255        theString;
  316.  
  317.     index = CountMItems(theMenu);
  318.     while (index) {
  319.         GetMenuItemText(theMenu, index, theString);
  320.         if (PStrCmp( (char *) theString, (char *) theItemString))
  321.             return(index);
  322.         index--;
  323.     }
  324.     return(0);
  325. }
  326.  
  327.  
  328. static short FontToItem(short fontFamilyNumber)
  329.  
  330. {    Str255        fontName;
  331.  
  332.     GetFontName(fontFamilyNumber, fontName);
  333.     return(ItemStringToItem(fontName, GetMenuHandle(idDisplayMenu)));
  334. }
  335.  
  336.  
  337. //
  338. //    PrepareMenus is called before the user pulls down a menu from the menu
  339. //    bar or types a command key equivalent. PrepareMenus enables and disables
  340. //    menu items within the current program context. Any other menu related
  341. //    setup may be performed here.
  342. //
  343.  
  344. void PrepareMenus(void)
  345. {
  346.     MenuHandle        theMenu;
  347.     DocumentPtr     theDocument;
  348.     WindowPtr        theWindow = FrontWindow() ;
  349.     short            teSelection, theMode;
  350.     Str255            theStr;
  351.  
  352.     theDocument = GetDocumentFromWindow(theWindow);
  353.     teSelection = (short) theDocument->documentGroup;
  354.  
  355.     theMenu = GetMenuHandle(idFileMenu);
  356.  
  357.     SetItemEnable(theMenu, NewItem,   gDocumentCount < MaxDocumentCount);
  358.     SetItemEnable(theMenu, OpenItem,  gDocumentCount < MaxDocumentCount);
  359.  
  360.     SetItemEnable(theMenu, CloseItem, theDocument != 0L);
  361.     SetItemEnable(theMenu, SaveItem, (theDocument) && (theDocument->dirty));
  362.     SetItemEnable(theMenu, SaveAsItem, theDocument != 0L);
  363.     SetItemEnable(theMenu, RevertItem, (theDocument) &&
  364.                                        (theDocument->theFileSpec.parID != 0 ) &&
  365.                                        (theDocument->theFileSpec.vRefNum != 0 ));
  366. #ifdef PODIUM_APP
  367.     SetItemEnable(theMenu, ImportItem, theWindow != nil ) ;
  368. #endif
  369.  
  370.     SetItemEnable(theMenu, PageSetupItem, false);
  371.     SetItemEnable(theMenu, PrintItem, false);
  372.  
  373.     theMenu = GetMenuHandle(idEditMenu);
  374.  
  375.     GetIndString(theStr, MenuStringsID, gCanUndoDrag);
  376.     SetMenuItemText(theMenu, iUndo, theStr);
  377.     SetItemEnable(theMenu, iUndo, gCanUndoDrag != slCantUndo);
  378.  
  379.     SetItemEnable(theMenu, iCut, teSelection);
  380.     SetItemEnable(theMenu, iCopy, teSelection);
  381.     SetItemEnable(theMenu, iPaste, theDocument != 0L);
  382.     SetItemEnable(theMenu, iClear, teSelection);
  383.     SetItemEnable(theMenu, iSelectAll, theDocument != 0L);
  384.     SetItemEnable(theMenu, iShowClipboard, false);
  385.  
  386. #ifdef PODIUM_APP
  387.     theMenu = GetMenuHandle(idSlides);
  388.     SetItemEnable(theMenu, 0, theWindow != nil);
  389.     
  390.     if(theWindow != nil ) {
  391.     
  392.         SetItemEnable(theMenu, iNext, false);        // dummy item, never used
  393.         SetItemEnable(theMenu, iPrevious, false);        // dummy item, never used
  394.         SetItemEnable(theMenu, iIndex, false);        // dummy item, never used
  395.     
  396.         SetItemEnable(theMenu, iRotateModel, true);        
  397.         SetItemEnable(theMenu, iHideShowMenu, true);        
  398.         CheckItem(theMenu, iRotateModel, theDocument->animateModel);
  399.     }
  400.  
  401. #else
  402.     theMenu = GetMenuHandle(idDisplayMenu);
  403.  
  404.     SetItemEnable(theMenu, iShaded, false);
  405.     SetItemEnable(theMenu, iLighted, false);
  406.     SetItemEnable(theMenu, iAnimated, false);
  407.     SetItemEnable(theMenu, iRenderer, false);
  408.     SetItemEnable(theMenu, iBackFacing, false);
  409.     
  410.     if (theDocument) {
  411.         theMode = 0;
  412.  
  413.         if( theDocument->documentGroup) {
  414.             MenuHandle        subMenu;
  415.  
  416.             SetItemEnable(theMenu, iShaded, true);
  417.  
  418.             subMenu = GetMenu(idStyleMenu);
  419.  
  420.             CheckItem(subMenu, iGouraud, false);
  421.             CheckItem(subMenu, iPhong, false);
  422.             CheckItem(subMenu, iFlat, false);
  423.  
  424.             if( theDocument->currentInterpolation == kQ3InterpolationStyleNone) {
  425.                 CheckItem(subMenu, iFlat, true);
  426.             } else if( theDocument->currentInterpolation == kQ3InterpolationStylePixel) {
  427.                 CheckItem(subMenu, iPhong, true);
  428.             } else {
  429.                 CheckItem(subMenu, iGouraud, true);
  430.             }
  431.  
  432.             SetItemEnable(theMenu, iRenderer, true);
  433.             subMenu = GetMenu(idRendererMenu);
  434.  
  435.             CheckItem(subMenu, iWF, false);
  436.             CheckItem(subMenu, iCTSW, false);
  437.             CheckItem(subMenu, iCTHW, false);
  438.  
  439.             {
  440.                 TQ3Object    renderer;
  441.                 
  442.                 Q3View_GetRenderer(theDocument->theView, &renderer);
  443.                 
  444.                 switch(Q3Object_GetLeafType(renderer)) {
  445.                     case kQ3RendererTypeWireFrame:
  446.                         CheckItem(subMenu, iWF, true);
  447.                         break;
  448.  
  449.                     case kQ3RendererTypeInteractive:
  450.                         if(!gUsingHardware) {
  451.                             CheckItem(subMenu, iCTSW, true);
  452.                         }
  453.                         else {
  454.                             CheckItem(subMenu, iCTHW, true);
  455.                         }
  456.                         break;
  457.                     default:
  458.                         break;
  459.                 }
  460.                 Q3Object_Dispose(renderer);
  461.             } 
  462.             
  463.             SetItemEnable(theMenu, iLighted, true);
  464.             if( theDocument->light == kQ3True) {
  465.                 CheckItem(theMenu, iLighted, true);
  466.             } else {
  467.                 CheckItem(theMenu, iLighted, false);
  468.             }
  469.  
  470.             SetItemEnable(theMenu, iAnimated, true);
  471.             subMenu = GetMenu(idAnimateMenu);
  472.  
  473.             if( theDocument->animateLights == kQ3True) {
  474.                 CheckItem(subMenu, iLights, true);
  475.             } else {
  476.                 CheckItem(subMenu, iLights, false);
  477.             }
  478.  
  479.             if( theDocument->animateModel == kQ3True) {
  480.                 CheckItem(subMenu, iModel, true);
  481.             } else {
  482.                 CheckItem(subMenu, iModel, false);
  483.             }
  484.             
  485.             SetItemEnable(theMenu, iBackFacing, true);
  486.         }
  487.     }
  488. #endif
  489.     DrawMenuBar() ;
  490. }
  491.  
  492.  
  493. static short DoSpecialPaste(DocumentPtr theDocument)
  494.  
  495. {    long        size, offset;
  496.     Handle        theData;
  497.  
  498.     size = GetScrap(0L, 'UPRC', &offset);
  499.  
  500.     if (size <= 0)
  501.         return(0);
  502.  
  503.     theData = NewHandle(size);
  504.     GetScrap(theData, 'UPRC', &offset);
  505.  
  506.     HLock(theData);
  507.     PutScrap(size, 'test', *theData);
  508.  
  509.     HUnlock(theData);
  510.     DisposeHandle(theData);
  511.  
  512.     return(0);
  513. }
  514.  
  515. static void DoPaste(DocumentPtr theDocument)
  516.  
  517. {    long            size, offset;
  518.     Handle            theData;
  519.     long            anErr= noErr;
  520.     TQ3SharedObject    viewHints ;
  521.     
  522.     anErr = LoadScrap();
  523.     if (anErr == noErr) {
  524.         size = GetScrap(0L, '3DMF', &offset);
  525.     
  526.         if (size > 0) {
  527.             TQ3FileObject         fd;
  528.             TQ3StorageObject         storage;
  529.             TQ3Object             objects = nil;
  530.     
  531.             theData = NewHandle(size);
  532.             if( theData ) {
  533.                 GetScrap(theData, '3DMF', &offset);
  534.             
  535.                 HLock(theData);
  536.         
  537.                 /* Read from clipboard */
  538.                 storage = Q3MemoryStorage_New((unsigned char *) *theData, (unsigned long) size);
  539.                 
  540.                 if (storage == nil)
  541.                     goto bail;
  542.                 
  543.                 fd = Q3File_New();
  544.                 Q3File_SetStorage(fd, storage);
  545.                 Q3Object_Dispose(storage);
  546.                 
  547.                 if (fd == nil)
  548.                     goto bail;
  549.                 
  550.                 Tumbler_ReadScene(    fd,
  551.                                     false,
  552.                                     &viewHints,
  553.                                     &theDocument->documentGroup) ;
  554.                 
  555.                 TumblerDocument_UpdateView( theDocument, viewHints ) ;
  556.                 
  557.                 AdjustLightsPositions(theDocument);
  558.             
  559.                 if (viewHints != NULL )
  560.                     Q3Object_Dispose(viewHints);
  561.  
  562.                 DrawOffscreen(theDocument);
  563.                 // DrawControls(theDocument->theWindow);
  564.                 DoDrawGrowIcon(theDocument->theWindow);
  565.             bail:
  566.                 Q3Object_Dispose(fd);
  567.         
  568.                 HUnlock(theData);
  569.                 DisposeHandle(theData);
  570.             }
  571.         } else {
  572.             size = GetScrap(0L,'PICT', &offset);
  573.             
  574.             if( size > 0 && theDocument->documentGroup) {
  575.                 TQ3StoragePixmap         textureImage;        
  576.                 theData = NewHandle(size);
  577.                 
  578.                 if( theData ) {
  579.                     GetScrap(theData, 'PICT', &offset);
  580.                 
  581.                     HLock(theData);
  582.             
  583.                     if( TextureFromPICT( (PicHandle) theData, &textureImage) == kQ3True ) {
  584.     
  585.                         if( AddTextureToDocument( theDocument, &textureImage) == kQ3Success ) {
  586.     
  587.                             DrawOffscreen(theDocument);
  588.                             
  589.                             // DrawControls(theDocument->theWindow);
  590.                             DoDrawGrowIcon(theDocument->theWindow);
  591.                         } else {
  592.                             Alert(130, 0L);
  593.                         }
  594.                     } else {
  595.                         Alert(130, 0L);
  596.                     }
  597.                     HUnlock(theData);
  598.                     DisposeHandle(theData);
  599.                 } else {
  600.                     Alert(130, 0L);
  601.                 }
  602.             }
  603.         }
  604.     }
  605. }
  606.  
  607.  
  608. //
  609. //    DoMenuCommand dispatches menu command routines from a menu select parameter.
  610. //    This function is called when the user selects a menu item with the mouse
  611. //    or types a command key equivalent.
  612. //
  613.  
  614. void DoMenuCommand(long select)
  615.  
  616. {    short        theMenuID, theItem, result;
  617.     MenuHandle    theMenu;
  618.     Str255        theName;
  619.     WindowPtr    theWindow;
  620.     DocumentPtr theDocument;
  621.  
  622.     theDocument = GetDocumentFromWindow(theWindow = FrontWindow());
  623.  
  624.     theItem   = LoWord(select);
  625.     theMenuID = HiWord(select);
  626.     theMenu   = GetMenuHandle(theMenuID);
  627.     switch(theMenuID) {
  628.         case idAppleMenu:
  629.             switch(theItem) {
  630.                 case AboutItem:
  631.                     result = Alert(256, 0L);
  632.                     break;
  633.                 default:
  634.                     GetMenuItemText(GetMenuHandle(idAppleMenu), theItem, theName);
  635.                     OpenDeskAcc(theName);
  636.             }
  637.             break;
  638.         case idFileMenu:
  639.             switch(theItem) {
  640.             
  641.                 case NewItem:
  642.                     DoNewDocument();
  643.                     break;
  644.                     
  645.                 case OpenItem:
  646.                     DoOpenDocument(theDocument);
  647.                     break;
  648. #ifdef PODIUM_APP
  649.                 case ImportItem:
  650.                     DoImport3DMFDocument(theDocument);
  651.                     break;
  652. #endif                    
  653.                 case CloseItem:
  654.                     if (theDocument) {
  655.                         (void)CloseDocument(theDocument);        // it's not important what the result is here
  656.                     }
  657.                     break;
  658.                     
  659.                 case SaveItem:
  660.                     if (theDocument)
  661.                         DidSaveDocument(theDocument);
  662.                     break;
  663.                     
  664.                 case SaveAsItem:
  665.                     if (theDocument)
  666.                         DoSaveAsDocument(theDocument);
  667.                     break;
  668.                     
  669.                 case RevertItem:
  670.                     if (theDocument)
  671.                         DoRevertDocument(theDocument);
  672.                     break;
  673.                     
  674.                 case QuitItem:
  675.                     // to quit we just send ourselves an appleEvent
  676.                     SendQuitApp() ;
  677.                     break;
  678.             }
  679.             break;
  680.         case idEditMenu:
  681.             switch(theItem) {
  682.                 case iUndo:
  683.                     break;
  684.                     
  685.                 case iCut:
  686.                     if (theDocument) {
  687.                         DoCopy(theDocument, true);
  688.                     }
  689.                     break;
  690.                     
  691.                 case iCopy:
  692.                     if (theDocument) {
  693.                         DoCopy(theDocument, false);
  694.                     }
  695.                     break;
  696.                     
  697.                 case iPaste:
  698.                     if (theDocument) {
  699.                         DoPaste(theDocument);
  700.                     }
  701.                     UpdateWindow( theDocument->theWindow ) ;
  702.                      break;
  703.                     
  704.                 case iClear:
  705.                     break;
  706.                     
  707.                 case iSelectAll:
  708.                     break;
  709.                     
  710.             }
  711.             break;
  712. #ifndef PODIUM_APP
  713.         case idDisplayMenu:
  714.  
  715.             switch(theItem) {
  716.                 case iBGColor:
  717.                     {
  718.                         TQ3DrawContextObject        drawCtx ;
  719.                         RGBColor                    currentRGBClearColor = { 0xffff, 0xffff, 0xffff } ;
  720.                         RGBColor                    newRGBClearColor ;
  721.                         
  722.                         Point                        wherePt = { 0, 0 } ;
  723.                         float                        factor = 0xffff ;
  724.                         GrafPtr                        savedPort ;
  725.  
  726.                         
  727.                         Q3View_GetDrawContext( theDocument->theView, &drawCtx ) ;
  728.                         
  729.                         currentRGBClearColor.red *= theDocument->clearColor.r ;
  730.                         currentRGBClearColor.green *= theDocument->clearColor.g ;
  731.                         currentRGBClearColor.blue *= theDocument->clearColor.b ;
  732.                         
  733.                         // query the user for a color
  734.                         if(GetColor(wherePt,"\pChoose a new background color",¤tRGBClearColor,&newRGBClearColor)) {
  735.                         
  736.                             theDocument->clearColor.r = newRGBClearColor.red / factor ;
  737.                             theDocument->clearColor.g = newRGBClearColor.green / factor ;
  738.                             theDocument->clearColor.b = newRGBClearColor.blue / factor ;
  739.                             
  740.                             Q3DrawContext_SetClearImageColor( drawCtx, &theDocument->clearColor ) ;
  741.                             
  742.                         }
  743.                         
  744.                         Q3Object_Dispose( drawCtx ) ;
  745.                         
  746.                         GetPort( &savedPort ) ;
  747.                         SetPort( (GrafPtr)theDocument->theWindow) ;
  748.                         InvalRect( &theDocument->theWindow->portRect ) ;
  749.                         SetPort( savedPort ) ;
  750.                                             
  751.                     }
  752.                     break ;
  753.                 case iLighted:
  754.                     if( theDocument->light == kQ3True) {
  755.                         TQ3GroupPosition        lightPosition;
  756.                         TQ3LightObject        theLight;
  757.                         TQ3GroupObject        lightGroup;
  758.                                 
  759.                         theDocument->light = kQ3False;
  760.                         
  761.                         Q3View_GetLightGroup(theDocument->theView, &lightGroup);
  762.                         Q3Group_GetFirstPosition(lightGroup, &lightPosition);
  763.                         
  764.                         /* First one is always on, skip */
  765.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  766.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  767.                         Q3Light_SetState(theLight,kQ3False);
  768.                         Q3Object_Dispose(theLight);                        
  769.                         
  770.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  771.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  772.                         Q3Light_SetState(theLight,kQ3False);                        
  773.                         Q3Object_Dispose(theLight);                        
  774.                         
  775.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  776.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  777.                         Q3Light_SetState(theLight,kQ3False);                        
  778.                         Q3Object_Dispose(theLight);                        
  779.  
  780.                         Q3Object_Dispose(lightGroup);
  781.                         CheckItem(theMenu, theItem, false);
  782.                     }else {    
  783.                         TQ3GroupPosition        lightPosition;
  784.                         TQ3LightObject        theLight;
  785.                         TQ3GroupObject    lightGroup;
  786.                                 
  787.                         theDocument->light = kQ3True;
  788.                         
  789.                         Q3View_GetLightGroup(theDocument->theView, &lightGroup);
  790.                         Q3Group_GetFirstPosition(lightGroup, &lightPosition);
  791.                         
  792.                         /* First one is always on, skip */
  793.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  794.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  795.                         Q3Light_SetState(theLight,kQ3True);
  796.                         Q3Object_Dispose(theLight);                        
  797.                         
  798.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  799.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  800.                         Q3Light_SetState(theLight,kQ3True);                        
  801.                         Q3Object_Dispose(theLight);                        
  802.                         
  803.                         Q3Group_GetNextPosition(lightGroup, &lightPosition);
  804.                         Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
  805.                         Q3Light_SetState(theLight,kQ3True);                        
  806.                         Q3Object_Dispose(theLight);                        
  807.  
  808.                         Q3Object_Dispose(lightGroup);
  809.                         
  810.                         CheckItem(theMenu, theItem, true);
  811.                     }
  812.                         
  813.                     DrawOffscreen(theDocument);
  814.                     UpdateWindow( theDocument->theWindow ) ;
  815.                     if( theDocument->viewHints ) {
  816.                         Q3Object_Dispose(theDocument->viewHints);
  817.                     }
  818.                     theDocument->viewHints = Q3ViewHints_New(theDocument->theView);
  819.                     DoDrawGrowIcon(theDocument->theWindow);
  820.                     break;
  821.                     
  822.                 default:
  823.                     break;
  824.             }
  825.             break;
  826.             
  827. #endif 
  828.  
  829.         case idAnimateMenu:
  830.             if( theItem == iModel ) {
  831.                 if( theDocument->animateModel == kQ3True) {
  832.                     theDocument->animateModel = kQ3False;
  833.                     CheckItem(theMenu, theItem, false);
  834.                 }else {
  835.                     theDocument->animateModel = kQ3True;
  836.                     CheckItem(theMenu, theItem, true);
  837.                 }
  838.             } else if( theItem == iLights) {
  839.                 if( theDocument->animateLights == kQ3True) {
  840.                     theDocument->animateLights = kQ3False;
  841.                     CheckItem(theMenu, theItem, false);
  842.                 }else {
  843.                     theDocument->animateLights = kQ3True;
  844.                     CheckItem(theMenu, theItem, true);
  845.                 }
  846.             }    
  847.             break;
  848.         
  849.         case idRendererMenu:
  850.             {
  851.                 TQ3DrawContextObject        myDrawContext;
  852.                 // set the doupble buffer state to false, make the active buffer
  853.                 // to be the front buffer
  854.                 gUsingHardware = false ;
  855.                 Q3View_GetDrawContext(theDocument->theView, &myDrawContext) ;
  856.                 Q3DrawContext_SetDoubleBufferState(  myDrawContext, kQ3True ) ;
  857.                 Q3Object_Dispose( myDrawContext ) ;
  858.             }
  859.             switch(theItem) {
  860.                 case iWF:
  861.                     Q3View_SetRendererByType(theDocument->theView,kQ3RendererTypeWireFrame);
  862.                     CheckItem(theMenu, iCTHW, false);
  863.                     CheckItem(theMenu, iCTSW, false);
  864.                     CheckItem(theMenu, iWF, true);
  865.                     theDocument->shaded = kQ3False;
  866.                     break;
  867.                 case iCTSW:
  868.                     {
  869.                         {
  870.                             TQ3RendererObject rendererObject;
  871.                             
  872.                             rendererObject = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  873.                             Q3View_SetRenderer(theDocument->theView,rendererObject);
  874.                             
  875. #ifdef FINAL
  876.                             Q3InteractiveRenderer_SetPreferences(rendererObject, kQAVendor_Apple, kQAVendor_BestChoice);
  877. #else
  878.                             Q3InteractiveRenderer_SetPreferences(rendererObject, ZcVendor_Apple, ZcVendor_BestChoice);
  879. #endif
  880.                             Q3Object_Dispose(rendererObject);
  881.                         }
  882.                         CheckItem(theMenu, iWF, false);
  883.                         CheckItem(theMenu, iCTHW, false);
  884.                         CheckItem(theMenu, iCTSW, true);
  885.                         theDocument->shaded = kQ3True;
  886.                     }
  887.                     break;
  888.                 case iCTHW:
  889.                     {
  890.                         TQ3DrawContextObject        myDrawContext;
  891.                         // set the doupble buffer state to false, make the active buffer
  892.                         // to be the front buffer
  893.                         gUsingHardware = true ;
  894.  
  895.                         Q3View_GetDrawContext(theDocument->theView, &myDrawContext) ;
  896.                         Q3DrawContext_SetDoubleBufferState(  myDrawContext, kQ3False ) ;
  897.                         Q3Object_Dispose( myDrawContext ) ;
  898.                         
  899.                         {
  900.                             TQ3RendererObject rendererObject;
  901.                             
  902.                             rendererObject = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  903.                             Q3View_SetRenderer(theDocument->theView,rendererObject);
  904.                             
  905. #ifdef FINAL
  906.                             Q3InteractiveRenderer_SetPreferences(rendererObject, kQAVendor_BestChoice, 0);
  907. #else
  908.                             Q3InteractiveRenderer_SetPreferences(rendererObject, ZcVendor_BestChoice, 0);
  909. #endif
  910.                             Q3Object_Dispose(rendererObject);
  911.                         }
  912.                         CheckItem(theMenu, iWF, false);
  913.                         CheckItem(theMenu, iCTSW, false);
  914.                         CheckItem(theMenu, iCTHW, true);
  915.                         theDocument->shaded = kQ3True;
  916.                     }
  917.                     break;
  918.             }
  919.             DrawOffscreen(theDocument) ;
  920.             UpdateWindow( theDocument->theWindow ) ;
  921.             if( theDocument->viewHints ) {
  922.                 Q3Object_Dispose(theDocument->viewHints);
  923.             }
  924.             theDocument->viewHints = Q3ViewHints_New(theDocument->theView);
  925.             DoDrawGrowIcon(theDocument->theWindow) ;
  926.             break ;
  927.             
  928.         // menu to allow modification of the backfacing style
  929.         case idBackfacingMenu:
  930.             switch(theItem) {
  931.             
  932.                 case iDrawBoth:
  933.  
  934.                     Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleBoth);
  935.                     CheckItem(theMenu, iDrawBoth, true);
  936.                     CheckItem(theMenu, iRemoveBackfacing, false);
  937.                     CheckItem(theMenu, iFlipNormals, false);
  938.                     break;
  939.                     
  940.                 case iRemoveBackfacing:
  941.                 
  942.                     Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleRemove);
  943.                     CheckItem(theMenu, iDrawBoth, false);
  944.                     CheckItem(theMenu, iRemoveBackfacing, true);
  945.                     CheckItem(theMenu, iFlipNormals, false);
  946.                     break;
  947.                     
  948.                 case iFlipNormals:
  949.  
  950.                     Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleFlip);
  951.                     CheckItem(theMenu, iDrawBoth, false);
  952.                     CheckItem(theMenu, iRemoveBackfacing, false);
  953.                     CheckItem(theMenu, iFlipNormals, true);
  954.                     break;
  955.                     
  956.             }
  957.  
  958.             DrawOffscreen(theDocument);
  959.             UpdateWindow( theDocument->theWindow ) ;
  960.             
  961.             // DrawControls(theDocument->theWindow);
  962.             DoDrawGrowIcon(theDocument->theWindow);
  963.             break;
  964.         case idStyleMenu:
  965. //            DisableUndoDrag();
  966.             switch(theItem){
  967.                 case iFlat:
  968.                     theDocument->currentInterpolation = kQ3InterpolationStyleNone;
  969.                     CheckItem(theMenu, iGouraud, false);
  970.                     CheckItem(theMenu, iPhong, false);
  971.                     CheckItem(theMenu, iFlat, true);
  972.                     break;
  973.                 case iGouraud:
  974.                     theDocument->currentInterpolation = kQ3InterpolationStyleVertex;
  975.                     CheckItem(theMenu, iPhong, false);
  976.                     CheckItem(theMenu, iFlat, false);
  977.                     CheckItem(theMenu, iGouraud, true);
  978.                     break;
  979.                 case iPhong:
  980.                     theDocument->currentInterpolation = kQ3InterpolationStylePixel;
  981.                     CheckItem(theMenu, iGouraud, false);
  982.                     CheckItem(theMenu, iFlat, false);
  983.                     CheckItem(theMenu, iPhong, true);
  984.                     break;
  985.             }
  986.             
  987.             DrawOffscreen(theDocument);
  988.             UpdateWindow( theDocument->theWindow ) ;
  989.             DoDrawGrowIcon(theDocument->theWindow);
  990.             break;
  991. #ifdef PODIUM_APP
  992.         case idSlides:
  993.             switch(theItem){
  994.                 case iRotateModel:
  995.                     if( theDocument->animateModel == kQ3True )
  996.                         theDocument->animateModel = kQ3False ;
  997.                     else
  998.                         theDocument->animateModel = kQ3True ;
  999.                     break ;
  1000.                 case iHideShowMenu:
  1001.                     {
  1002.                         void ToggleMenuBar(void) ;
  1003.                         ToggleMenuBar() ;
  1004.                     }
  1005.                 default:
  1006.                     break ;
  1007.             }
  1008.             break ;
  1009. #endif            
  1010.         
  1011.         default:
  1012.             break;
  1013.     }
  1014.  
  1015. //    if ((theDocument = GetDocumentFromWindow(FrontWindow())) != nil)
  1016. //        TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  1017.  
  1018.     HiliteMenu(0);
  1019. }
  1020.  
  1021.